/*
 * CommandHelper.cpp
 *
 *  Created on: Apr 30, 2012
 *      Author: Steven Chang <schang@cs.umn.edu>
 */

#include "CommandHelper.h"

using namespace std;


const char* CommandHelper::DegreeProgramFormStatus[]= {"Not Submitted",
            "Submitted to Advisor",
            "Submitted to Department",
            "Submitted to Grad School",
            "Approved"
    };

const char* CommandHelper::Plan[] = {"Plan Unknown", "Plan A", "Plan B",
        "Plan C", "No Plan"
};

const char* ClassTypeNamesInit[] = {"Unknown", "Out of Department",
        "Theory", "Theory Foundation",
        "Architecture, System and Software",
        "Applications", "Colloquium", "CSCI8000",
		"Thesis", "Project"
};
const vector<string> CommandHelper::ClassTypeNames(ClassTypeNamesInit, ClassTypeNamesInit+10);

const char* TheoryInit[] = {"5421", "5403", "5304", "5302", "5471",
        "5481", "5525"};

const vector<string> CommandHelper::Theory(TheoryInit, TheoryInit + 7);

const char* TheoryFoundationInit[] = {"5421", "5403", "5304"};

const vector<string> CommandHelper::TheoryFoundation(TheoryFoundationInit, TheoryFoundationInit+3);

const char* ASSInit[] = {"5106", "5161", "5801", "5802", "5103", "5105",
        "5451", "5708", "5204", "5211", "5221", "5231"};

const vector<string> CommandHelper::ASS(ASSInit, ASSInit + 11);

const  char* ApplicationInit[] = {"5511", "5521", "5551", "5561",
        "5523", "5461", "5107", "5109", "5115", "5125", "5271"};

const vector<string> CommandHelper::Application(ApplicationInit, ApplicationInit+11);

const string CommandHelper::Colloquium = "8970";

const string CommandHelper::Thesis = "8777";

const string CommandHelper::Project = "8994";

/*
 * @return A string of name of the student by pretty print the name vector
 *
 */
const string CommandHelper::getName(std::vector<std::string> nameVector) throw(length_error){
    if(nameVector.size() < 2)
    {
        throw length_error("Student name not long enough!");
    }

    //Format the student's name
    string name = nameVector[nameVector.size() - 1] + ",";
    for (unsigned int j = 0; j < nameVector.size() - 1; j++)
    {
        name.append(" ");
        name.append(nameVector[j]);
    }
    return name;
}

/*
 * Get the student pointer based on the input. The input can be either the student ID
 * or the sequence number of student on the student list displayed from @ShowStudentList.
 *
 */
tr1::shared_ptr<TranscriptParser> CommandHelper::getStudent(const string param) throw(out_of_range){
    //param is a student ID
    tr1::shared_ptr<TranscriptParser> student(TranscriptFactory::getInstance(param));
    if(student==NULL) {
        unsigned int value = atoi(param.c_str());
        //param is a #number of the student list
        std::vector<TranscriptFactory::StudentInfo> studentList =
                TranscriptFactory::getStudentList();
        string id;
        if(value<1||value>studentList.size()) {
            throw out_of_range("Invalid input.(Only student ID and sequence number in the student list are valid)");
        }
        id = studentList[value-1].studentId;
        student.reset(TranscriptFactory::getInstance(id));
    }

    return student;
}

/*
 *  Check the if the course is over five years since admission
 *  @return true    if the course has expired
 *          false   if not
 */
bool CommandHelper::checkExpire(tr1::shared_ptr<TranscriptParser> student, Course &crs) {
    int courseYear = atoi(crs.year.c_str());
    char year[4];
    student->getDegreeAdmissionDate().copy(year, 4, 0);
    int admYear = atoi(year);
    return (courseYear - admYear)>5;
}

/*
 * Check if the course is in department
 * @return true     it is in department
 *         false    otherwise
 */
bool CommandHelper::inDepartment(Course &crs) {
    return crs.subject == "CSCI";
}

/*
 * Check if the course is in department
 * @return true     it is in department
 *         false    otherwise
 */
bool CommandHelper::gpaEligible(tr1::shared_ptr<TranscriptParser> student, Course &crs) {
	return crs.gradingOpt == 0 && crs.grade != "" && crs.grade != "X" && !checkExpire(student, crs);
}

CommandHelper::ClassType CommandHelper::getType(Course &crs) {
    if(!inDepartment(crs)) {
        return CommandHelper::OUTOFDEPARTMENT;
    }
    string number = crs.course;
    if(number.size() == 4) {
        if(number == CommandHelper::Colloquium) {
            return CommandHelper::COLLOQUIUM;
        }
		if(number == CommandHelper::Thesis) {
			return CommandHelper::THESIS;
		}
		if(number == CommandHelper::Project) {
			return CommandHelper::PROJECT;
		}
        if(number.c_str()[0] == '8') {
            return CommandHelper::CSCI8000;
        }
        if(find(TheoryFoundation.begin(), TheoryFoundation.end(), number)!=TheoryFoundation.end()){
            return CommandHelper::THEORY_FOUNDATIONS;
        }
        if(find(Theory.begin(), Theory.end(), number)!=Theory.end()){
            return CommandHelper::THEORY;
        }
        if(find(ASS.begin(), ASS.end(), number)!=ASS.end()){
            return CommandHelper::ARCHITECTUR_SYS_SOFTWARE;
        }
        if(find(Application.begin(), Application.end(), number)!=Application.end()){
            return CommandHelper::APPLICATION;
        }
    }
    return CommandHelper::UNKNOWN;

}
